#ifndef REMOTE_HANDLE_H
#define REMOTE_HANDLE_H

#include "Client.hpp"
#include "PixelFormat.hpp"
#include <atomic>
#include <condition_variable>
#include <fstream>
#include <mutex>
#include <oatpp-websocket/WebSocket.hpp>
#include <string>

struct CameraParament {
  int32_t ImageHeight;
  int32_t ImageWidth;
  int32_t ImageOffsetX;
  int32_t ImageOffsetY;
  int32_t ExposeTime;
  int32_t FrameRate;
  int32_t TriggerMode;
};

/**
 * @class RemoteHandle
 * @brief 处理远程指令，从旧框架移植过来
 *
 */
class RemoteHandle {
public:
  RemoteHandle(Client *evtHandler);
  virtual ~RemoteHandle();
  void SetCameraContrlHandler(Client *evtHandler);
  void StartSocket();
  void SetImage(unsigned char *image, const int32_t height, const int32_t width,
                const pixelFormat imgFormat);
  void SendDeviceStatus(int32_t value);
  void SendCameraPara(CameraParament cameraParament);
  void AcceptData(const char *aFrame, long size); // 用于接收数据，线程安全设计
  std::string SendData(); // 如果没有发送任务，这个函数会让当前线程休眠
  void SetSocket(std::shared_ptr<oatpp::websocket::WebSocket> &socket);
  void closeTask();
  void SendMessage(const std::string &msg);
  void FileTransfer(const std::string &filePath);
  void StopFileTransfer();
  void SendFileData(
      const std::shared_ptr<oatpp::websocket::WebSocket>
          &socket); // 文件数据传输调用,一直调用到传输结束为止，这样可以提高性能
  bool FileTransferFuncEnable();

private:
  Client *_evtHandler;
  Client *_cameraContralHandler = nullptr;
  std::condition_variable condSendReady; // 数据准备就绪后唤醒线程
  std::mutex sendDataMut;
  std::mutex sendImageMut;
  std::mutex sendCommandMut;
  std::string sendData;
  std::string sendCommand;
  std::atomic<bool> sendImageFlag = false;
  std::atomic<bool> sendDataFlag = false;
  std::atomic<bool> sendCommandFlag = false;
  std::atomic<bool> threadExitFlag = false;
  std::shared_ptr<oatpp::websocket::WebSocket> socketPtr;

  // 文件传输
  void SendFileTransferCommand(const int32_t &value);
  void SendFileTransferCommand(const char *value, size_t size);
  void GetFileTransferCommand();
  void SendAndGetFileTransferCommand(const char *value, size_t size);
  long allFrameCount = 0;
  std::ifstream iFile;
  std::atomic<bool> fileDataReady = false;
  std::mutex FileDataMutex;
  std::condition_variable condFileDataReady;
  std::atomic<bool> fileTransferFlag = false;
  bool fileTransferEnable = false;
};

#endif
